package com.guodi.model.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guodi.common.exception.BaseRuntimeException;
import com.guodi.common.utils.UuidUtil;
import com.guodi.core.secure.utils.AuthUtil;
import com.guodi.model.entity.*;
import com.guodi.model.mapper.IdtMonitorValueMapper;
import com.guodi.model.service.*;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @描述：指标监测值表 服务类
 * @作者: 彭辉
 * @日期: 2020-06-05
 */
@Service
public class IdtMonitorValueServiceImpl extends ServiceImpl<IdtMonitorValueMapper, IdtMonitorValue> implements IIdtMonitorValueService {

    @Resource
    private IdtMonitorValueMapper idtMonitorValueMapper;
    @Resource
    private IIdtIndicatorsService idtIndicatorsService;
    @Resource
    private IIdtReportValueService idtReportValueService;
    @Resource
    private IIdtTargetValueService iIdtTargetValueService;
    @Resource
    private IIdtWarnRuleService iIdtWarnRuleService;
    @Resource
    private IIdtYearRelevanceService iIdtYearRelevanceService;
    @Resource @Lazy
    private IIdtIndicatorsDirService idtIndicatorsDirService;
    /**
     * 指标数值相关操作类，主要是针对监测值的新增和修改    <br/>
     * 如果需要增加业务操作，请自行继承IIdtValueOperation接口，并交给spring管理
     */
//    @Autowired
    private List<IIdtValueOperation<IdtMonitorValue>> idtValueOperationList;
    /**
     * 月度更新
     */
    private static final String IDT_UPDATE_CYCLE_MONTH = "month";
    /**
     * 年度更新
     */
    private static final String IDT_UPDATE_CYCLE_YEAR = "year";
    /**
     * 季度更新
     */
    private static final String IDT_UPDATE_CYCLE_QUARTER = "quarter";
    /**
     * monitor_time 为年时的长度
     */
    private static final int MONITOR_TIME_YEAR_LENGTH = 4;
    /**
     * monitor_time 为月时的长度
     */
    private static final int MONITOR_TIME_MONTH_LENGTH = 7;
    /**
     * monitor_time 为季时的长度
     */
    private static final int MONITOR_TIME_QUARTER_LENGTH = 6;

    @Override
    public void deleteByIds(String... ids) {
        List<String> idList = Arrays.asList(ids);
        Collection<IdtMonitorValue> idtMonitorValues = this.listByIds(idList);
        this.removeByIds(idList);
        // 更新指标预警状态
        List<String> stringList = idtMonitorValues.stream().map(x -> x.getIndicatorsId()).collect(Collectors.toList());
        idtIndicatorsService.updateStatus(String.join(",", stringList));
        for (IdtMonitorValue idtMonitorValue :idtMonitorValues) {
            // 更新对应年份的上报值的是否统一字段
            idtReportValueService.updateUnify(idtMonitorValue.getIndicatorsId(), idtMonitorValue.getYear() + "", idtMonitorValue.getDivisionCode());
        }
    }

    @Override
    public List<IdtMonitorValue> listByKeyWord(String keyWord, Integer year, long pageSize, long start, String sort, String sortWay, String divisionCode, String orgId) {
        return idtMonitorValueMapper.listByKeyWord(keyWord,year,pageSize,start,sort,sortWay,divisionCode,orgId);
    }

    @Override
    public Integer listByKeyWordCount(String keyWord,String orgId) {
        return idtMonitorValueMapper.listByKeyWordCount(keyWord,orgId);
    }

    @Override
    public Integer listByKeyWordAndCodeCount(String keyWord, Integer year, String divisionCode, String orgId) {
        return idtMonitorValueMapper.listByKeyWordAndCodeCount(keyWord,year,divisionCode,orgId);
    }

    @Override
    public String getNameByDivisionCode(String divisionCode) {
        return idtMonitorValueMapper.getNameByDivisionCode(divisionCode);
    }

    @Override
    public List<IdtMonitorValue> getHistoryList(String indicatorsId, List<String> monitorTimeList, String divisionCode) {
        return idtMonitorValueMapper.getHistoryList(indicatorsId, monitorTimeList, divisionCode);
    }

    @Override
    public List<IdtMonitorValue> getNewestData(String indicatorsId) {
        QueryWrapper<IdtMonitorValue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("indicators_id", indicatorsId);
        queryWrapper.orderByDesc("monitor_time", "create_time");
        List<IdtMonitorValue> idtMonitorValues = this.list(queryWrapper);
        List<IdtMonitorValue> idtMonitorValueList = idtMonitorValues.stream().filter(x->x.getMonitorTime()!=null).collect(Collectors.toList());
        return idtMonitorValueList;
    }

    /**
     * @param indicatorsId
     * @param area
     * @param targetYear
     * @param targetValue
     * @描述:更新监测值预警状态字段（根据预警规划、检测值、规划值判断是否预警）
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2020/12/4 10:18
     */
    @Override
    public void updateWarnStatus(String indicatorsId, String area, String targetYear, String targetValue) {
        if(StringUtils.isBlank(indicatorsId)||StringUtils.isBlank(targetYear)){
            return;
        }
        //查询该规划目标年的对标关系
        LambdaQueryWrapper<IdtYearRelevance> lambda = new QueryWrapper().lambda();
        lambda.eq(IdtYearRelevance::getIndicatorsId,indicatorsId);
        lambda.eq(IdtYearRelevance::getPlanTargetYear,Integer.valueOf(targetYear));
        List<IdtYearRelevance> idtYearRelevances = iIdtYearRelevanceService.list(lambda);
        List<IdtMonitorValue> list = new ArrayList<>();
        if(idtYearRelevances!=null&&idtYearRelevances.size()>0){
            for (IdtYearRelevance idtYearRelevance: idtYearRelevances) {
                String monitorReportYear = idtYearRelevance.getMonitorReportYear();
                String[] split = monitorReportYear.split("-");
                if(split!=null && split.length==2){
                    int starYear = Integer.valueOf(split[0]);
                    int endYear = Integer.valueOf(split[1]);
                    //查询该规划目标年对应的所有监测值
                    LambdaQueryWrapper<IdtMonitorValue> lambda1 = new QueryWrapper().lambda();
                    lambda1.eq(IdtMonitorValue::getIndicatorsId, indicatorsId);
                    lambda1.eq(IdtMonitorValue::getDivisionCode, area);
                    lambda1.ge(IdtMonitorValue::getYear, starYear);
                    lambda1.le(IdtMonitorValue::getYear, endYear);
                    List<IdtMonitorValue> list1 = this.list(lambda1);
                    if(list1!=null){
                        list.addAll(list1);
                    }
                }
            }
        }

        if(list.size()>0){
            //查询预警规则
            IdtWarnRule warnRule = iIdtWarnRuleService.listWarnRuleById(indicatorsId);
            String idtWarnRules = null;
            if(null != warnRule){
                idtWarnRules =  warnRule.getName();
            }
            //判断是否预警
            for (IdtMonitorValue idtMonitorValue: list) {
                String value = idtMonitorValue.getMonitorValue();
                String warnStatu = null;
                //当预警规则为空或目标值为空或监测值为空时，预警状态未空值
                if(StringUtils.isBlank(targetValue) || StringUtils.isBlank(value)){
                    warnStatu = null;
                } else {
                    if ("正向".equals(idtWarnRules)) {
                        if (Float.parseFloat(value) > Float.parseFloat(targetValue)) {
                            warnStatu = "正常";
                        } else {
                            warnStatu = "预警";
                        }
                    } else if ("反向".equals(idtWarnRules)) {
                        if (Float.parseFloat(value) < Float.parseFloat(targetValue)) {
                            warnStatu = "正常";
                        } else {
                            warnStatu = "预警";
                        }
                    }
                }
                idtMonitorValue.setWarnStatus(warnStatu);
            }
            //批量更新规划目标年对应所有监测值的是否预警字段
            this.updateBatchById(list);
        }
    }

    /**
     * @描述: 根据父级地区编码，查询其直接子级
     * @入参: parentDivisionCode 父级行政区编码
     * @出参: 直接子级
     * @作者: 陈宏成
     * @日期: 2021/01/14
     **/
    @Override
    public List<ApiMapDivision> listDirectChildDivision(String parentDivisionCode){
        return idtMonitorValueMapper.listDirectChildDivision(parentDivisionCode);
    }

    /**
     * @描述：根据指标编码、年份、行政区划代码查询因子值
     * @作者：汤厚韬
     * @日期：2021/1/25
     */
    @Override
    public List<IdtMonitorValue> listByIndicatorsIds(List<String> calculateFactorNameList, String time, String divisionCode) {
        return idtMonitorValueMapper.listByIndicatorsIds(calculateFactorNameList, time, divisionCode);
    }

    /**
     * @作者: 林楷 2021/4/27
     * @描述: 计算指标监测值年均增速
     * @参数: indicatorsId：指标模型ID
     * @参数: divisionCode：行政区划编号
     * @返回:
     */
    @Override
    public List<ApiIndicatorsGrowthRate> computeYearGrowthRateByIndicatorsAndDivision(String indicatorsId, String divisionCode) {
        return idtMonitorValueMapper.computeYearGrowthRateByIndicatorsAndDivision(indicatorsId, divisionCode);
    }

    /**
     * 计算监测值的平均值
     * @入参： idtIdList 指标id列表
     * @入参： divisionCode 行政区划编码列表
     * @出参： List<IdtMonitorValue> 只会有三个值indicators_id, division_code, monitor_value。其中monitor_value为平均值
     * @作者： 陈宏成
     * @日期： 2021/11/9
     */
    @Override
    public List<IdtMonitorValue> listAvgMonitorValue(List<String> idtIdList, List<String> divisionCodes){
        if (idtIdList == null || divisionCodes == null || divisionCodes.isEmpty() || idtIdList.isEmpty()){
            return new LinkedList<>();
        }
        // 查指标
        LambdaQueryWrapper<IdtIndicators> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(IdtIndicators::getId, idtIdList);
        queryWrapper.select(IdtIndicators::getId, IdtIndicators::getUpdateCycle);
        List<IdtIndicators> idtIndicators = this.idtIndicatorsService.list(queryWrapper);
        // 划分年月季更新周期
        Map<String, List<IdtIndicators>> collect = idtIndicators.stream().collect(Collectors.groupingBy(IdtIndicators::getUpdateCycle));
        // 结果
        List<IdtMonitorValue> avgValueList = new LinkedList<>();
        for(Map.Entry<String, List<IdtIndicators>> stringListEntry : collect.entrySet()) {
            if (stringListEntry.getValue() == null || stringListEntry.getValue().isEmpty()){
                continue;
            }
            String updateCycle = stringListEntry.getKey();
            if ("year".equals(updateCycle) || "month".equals(updateCycle) || "quarter".equals(updateCycle)){
                List<String> ids = stringListEntry.getValue().stream().map(IdtIndicators::getId).collect(Collectors.toList());
                List<IdtMonitorValue> monitorValueList = this.idtMonitorValueMapper.listAvgMonitorValue(ids, divisionCodes, updateCycle);
                avgValueList.addAll(monitorValueList);
            }
        }
        return avgValueList;
    }

    /**
     * @作者: 陈宏成  2021-08-04
     * @描述:   计算上一监测值，根据更新周期，如果是年度更新，就查指标监测值里面monitor_time为年度的上一条监测值，
     *         如果上一年没有，则往前继续追溯。如果是月度更新，就查指标监测值里面monitor_time为月度的上一条监测值
     * @参数: indicatorsId：指标模型ID
     * @参数: divisionCode：行政区划编号
     * @参数: currentUpdateTime：当前更新时间，会查询比这个更新时间更早的上次更新的记录，格式: yyyy 或者 yyyy-MM 或者 yyyy-M
     * @参数: currentUpdateTime：当前更新时间，会查询比这个更新时间更早的上次更新的记录，年：2020；月：2020-01；季度：2020-1
     * @参数: updateCycle: 更新周期，1-年度，2-月度，3-季度（或者：year-年度，month-月度，quarter-季度）
     * @返回:
     */
    @Override
    public IdtMonitorValue getLastMonitorValue(String indicatorsId, String divisionCode, String currentUpdateTime, String updateCycle){
        if (Objects.equals("year",updateCycle)){
            updateCycle = "1";
        }else if(Objects.equals("month",updateCycle)){
            updateCycle = "2";
        }else if(Objects.equals("quarter",updateCycle)){
            updateCycle = "3";
        }
        return this.idtMonitorValueMapper.getLastMonitorValue(indicatorsId, divisionCode,currentUpdateTime, updateCycle );
    }

    /**
     * 计算指标预警状态
     * @param indicatorsId 指标id
     * @param monitorValue 监测值
     * @param monitorTime 监测时间
     * @param divisionCode 行政区划编码
     * @return 预警状态，例如：#EE3E3E,重度预警
     * @author 陈宏成
     * @date 2021-12-30 重写
     */
    @Override
    public String getWarnStatus(String indicatorsId, String monitorValue, String monitorTime, String divisionCode) {

        if(StringUtils.isBlank(indicatorsId)||StringUtils.isBlank(monitorTime)||StringUtils.isBlank(divisionCode)||StringUtils.isBlank(monitorValue)){
            throw new BaseRuntimeException("指标ID、监测值、监测时间、指标行政区划编码不能为空");
        }
        // 暂时只是更新监测值--20210816
        ApiIndicatorsVal apiIndicatorsVal = idtIndicatorsService.getIdtVal(indicatorsId, monitorTime, divisionCode, false, false);
        apiIndicatorsVal.setMonitorValue(monitorValue);
        apiIndicatorsVal.setMonitorTime(monitorTime);
        String warnStatus = idtIndicatorsService.updateWarnStatus(apiIndicatorsVal);
        return warnStatus;
    }

    /**
     * 检查时间字符串是否符合监测时间规范
     * @入参： monitorTime 监测时间，年：2020；月：2020-05；季：2020-4
     * @入参： isThrowException 不符合规范时是否抛出异常
     * @出参: false -- 不规范，true -- 规范
     * @作者： 陈宏成
     * @日期： 2021/11/16
     */
    @Override
    public boolean checkMonitorTime(String monitorTime, boolean isThrowException){
        boolean isOk = false;
        if (StringUtils.isBlank(monitorTime)){
            isOk = false;
        }else{
            if (monitorTime.length() == 4){
                // 年
                isOk = Pattern.matches("[0-9]{4}", monitorTime);
            }else if(monitorTime.length() == 6){
                // 季度
                isOk = Pattern.matches("[0-9]{4}-[1-4]{1}", monitorTime);
            }else if(monitorTime.length() == 7){
                // 月
                isOk = Pattern.matches("[0-9]{4}-[0-9]{2}", monitorTime);
                if (isOk == true){
                    String[] split = monitorTime.split("-");
                    int month = Integer.parseInt(split[1]);
                    if (month <= 12 && month >= 1){
                        isOk = true;
                    }else{
                        isOk = false;
                    }
                }
            }
        }
        if (isThrowException == true && isOk == false){
            throw new BaseRuntimeException(monitorTime + " 不符合监测时间规范");
        }else{
            return isOk;
        }
    }

    /**
     * 检查时间字符串是否符合指标更新周期
     * @param idtId 指标id
     * @param monitorTime 监测时间，年：2020；月：2020-05；季：2020-4
     * @param isThrowException 不符合规范时是否抛出异常
     * @return false -- 不规范，true -- 规范
     * @author 陈宏成
     * @date 2021/12/23
     */
    @Override
    public boolean checkMonitorTimeAccordWithUpdateCycle(String idtId, String monitorTime, boolean isThrowException){
        // 检查时间字符串是否符合格式
        boolean isOk = this.checkMonitorTime(monitorTime, isThrowException);
        if (isOk == true && StringUtils.isNotBlank(idtId)){
            IdtIndicators byId = this.idtIndicatorsService.getById(idtId);
            if (Objects.equals(byId.getUpdateCycle(), IDT_UPDATE_CYCLE_YEAR) && monitorTime.length() == MONITOR_TIME_YEAR_LENGTH){
                isOk = true;
            }else if (Objects.equals(byId.getUpdateCycle(), IDT_UPDATE_CYCLE_MONTH) && monitorTime.length() == MONITOR_TIME_MONTH_LENGTH){
                isOk = true;
            }else if (Objects.equals(byId.getUpdateCycle(), IDT_UPDATE_CYCLE_QUARTER) && monitorTime.length() == MONITOR_TIME_QUARTER_LENGTH){
                isOk = true;
            }else{
                isOk = false;
            }
        }else{
            isOk = false;
        }
        if (isThrowException == true && isOk == false){
            throw new BaseRuntimeException(monitorTime + " 不符合指标更新周期");
        }else{
            return isOk;
        }
    }

    /**
     * （重写mybatis的保存方法）增加统一的额外操作    <br/><br/>
     * 所有更新监测值的都只能走这些接口
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(IdtMonitorValue entity) {
        entity.setCreateTime(new Date());
        try {
            entity.setCreator(AuthUtil.getUserId().toString());
        }catch (NullPointerException exception){
            // 避免获取不到userId而报错
        }
        entity.setModifyTime(null);
        entity.setModifier(null);

        // 上锁，避免进行业务操作时，其他人修改了最新的值
        synchronized (IdtMonitorValueServiceImpl.class){
            // 调用父类，执行简单保存
            boolean save = super.save(entity);
            // 执行额外的业务操作，如果需要增加业务操作，请自行继承IIdtValueOperation接口，并交给spring管理
            if (!CollectionUtils.isEmpty(this.idtValueOperationList)){
                for(IIdtValueOperation<IdtMonitorValue> idtValueOperation : this.idtValueOperationList) {
                    idtValueOperation.save(entity);
                }
            }
            return save;
        }
    }

    /**
     * （重写mybatis的保存方法）增加统一的额外操作    <br/><br/>
     * 所有更新监测值的都只能走这些接口
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(IdtMonitorValue entity) {
        entity.setModifyTime(new Date());
        try {
            entity.setModifier(AuthUtil.getUserId().toString());
        }catch (NullPointerException exception){
            // 避免获取不到userId而报错
        }
        entity.setCreateTime(null);
        entity.setCreator(null);

        // 上锁，避免进行业务操作时，其他人修改了最新的值
        synchronized (IdtMonitorValueServiceImpl.class) {
            // 调用父类，执行简单更新
            boolean update = super.updateById(entity);
            // 执行额外的业务操作，如果需要增加业务操作，请自行继承IIdtValueOperation接口，并交给spring管理
            if (!CollectionUtils.isEmpty(this.idtValueOperationList)) {
                for(IIdtValueOperation<IdtMonitorValue> idtValueOperation : this.idtValueOperationList) {
                    idtValueOperation.update(entity);
                }
            }
            return update;
        }
    }

    /**
     * （重写mybatis的保存方法）增加统一的额外操作    <br/><br/>
     * 所有更新监测值的都只能走这些接口
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean saveOrUpdate(IdtMonitorValue entity) {
        boolean b = this.saveOrUpdateBatch(Arrays.asList(entity));
        return b;
    }

    /**
     * （重写mybatis的保存方法）增加统一的额外操作    <br/><br/>
     * 所有更新监测值的都只能走这些接口
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean saveBatch(Collection<IdtMonitorValue> entityList) {
        boolean save = true;
        for(IdtMonitorValue idtMonitorValue : entityList) {
            save = save & this.save(idtMonitorValue);
        }
        return save;
    }

    /**
     * （重写mybatis的保存方法）增加统一的额外操作    <br/><br/>
     * 所有更新监测值的都只能走这些接口
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean saveOrUpdateBatch(Collection<IdtMonitorValue> entityList) {
        boolean update = true;
        for(IdtMonitorValue idtMonitorValue : entityList) {
            if (StringUtils.isBlank(idtMonitorValue.getId())){
                update = update & this.save(idtMonitorValue);
            }else{
                IdtMonitorValue byId = this.getById(idtMonitorValue.getId());
                if (byId == null){
                    update = update & this.save(idtMonitorValue);
                }else{
                    update = update & this.updateById(idtMonitorValue);
                }
            }
        }
        return update;
    }

    /**
     * （重写mybatis的保存方法）增加统一的额外操作    <br/><br/>
     * 所有更新监测值的都只能走这些接口
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean updateBatchById(Collection<IdtMonitorValue> entityList) {
        boolean update = true;
        for(IdtMonitorValue idtMonitorValue : entityList) {
            update = update & this.updateById(idtMonitorValue);
        }
        return update;
    }

    /**
     * 此方法禁用，saveBatch(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean saveBatch(Collection<IdtMonitorValue> entityList, int batchSize) {
        throw new RuntimeException("此方法禁用，saveBatch(Collection<IdtMonitorValue>)");
    }

    /**
     * 此方法禁用，请使用 saveOrUpdateBatch(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean saveOrUpdateBatch(Collection<IdtMonitorValue> entityList, int batchSize) {
        throw new RuntimeException("此方法禁用，请使用 saveOrUpdateBatch(Collection<IdtMonitorValue>)");
    }
    /**
     * 此方法禁用，请使用 updateBatchById(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean updateBatchById(Collection<IdtMonitorValue> entityList, int batchSize) {
        throw new RuntimeException("此方法禁用，请使用 updateBatchById(Collection<IdtMonitorValue> )");
    }

    /**
     * 此方法禁用，请使用 updateById(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean update(Wrapper<IdtMonitorValue> updateWrapper) {
        throw new RuntimeException("此方法禁用，请使用 updateById(IdtMonitorValue)");
    }

    /**
     * 此方法禁用，请使用 updateById(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean update(IdtMonitorValue entity, Wrapper<IdtMonitorValue> updateWrapper) {
        throw new RuntimeException("此方法禁用，请使用 updateById(IdtMonitorValue)");
    }

    /**
     * 此方法禁用，请使用 updateById(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public UpdateChainWrapper<IdtMonitorValue> update() {
        throw new RuntimeException("此方法禁用，请使用 updateById(IdtMonitorValue)");
    }

    /**
     * 此方法禁用，请使用 updateById(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public LambdaUpdateChainWrapper<IdtMonitorValue> lambdaUpdate() {
        throw new RuntimeException("此方法禁用，请使用 updateById(IdtMonitorValue)");
    }

    /**
     * 此方法禁用，请使用 saveOrUpdate(IdtMonitorValue)
     * @author 陈宏成
     * @date 2021-12-23
     */
    @Override
    public boolean saveOrUpdate(IdtMonitorValue entity, Wrapper<IdtMonitorValue> updateWrapper) {
        throw new RuntimeException("此方法禁用，请使用 saveOrUpdate(IdtMonitorValue)");
    }


    @Override
    public String getEstimateStatus(String code, String indicatorsId, String monitorValue, String monitorTime, String divisionCode){
        if(StringUtils.isBlank(indicatorsId)||StringUtils.isBlank(monitorTime)||StringUtils.isBlank(divisionCode)||StringUtils.isBlank(monitorValue)){
            throw new BaseRuntimeException("指标ID、监测值、监测时间、指标行政区划编码不能为空");
        }
        String result = "尚未配置规则";
        try {
            //先获取评估规则配置
            List<IdtIndicators> indicatorsList = idtIndicatorsDirService.getRuleByCode(code, Collections.singletonList(indicatorsId), monitorTime , divisionCode);
            if(CollectionUtils.isEmpty(indicatorsList)){
                return result;
            }
            IdtIndicators indicators = indicatorsList.get(0);
            if(indicators != null && !StringUtils.isEmpty(indicators.getEstimateRuleConfig())){
                String ruleJson = indicators.getEstimateRuleConfig();
                List<idtEstimateRuleValue> idtEstimateRuleValues = com.alibaba.fastjson.JSONArray.parseArray(ruleJson, idtEstimateRuleValue.class);
                ScriptEngineManager manager = new ScriptEngineManager();
                ScriptEngine engine = manager.getEngineByName("js");
                engine.put("MonitorValue",monitorValue);
                for(idtEstimateRuleValue ruleValue : idtEstimateRuleValues){
                    String rule = ruleValue.getEstimateRule();
                    if(rule.contains("~")){
                        double leftValue = Double.parseDouble(rule.substring(0, rule.indexOf("~")).trim());
                        double righeValue = Double.parseDouble(rule.substring(rule.indexOf("~") + 1).trim());
                        rule = leftValue + "<=MonitorValue && MonitorValue<" + righeValue;
                    }else {
                        rule = "MonitorValue" + rule;
                    }
                    Object obectResult = engine.eval(rule);
                    if ((boolean) obectResult) {
                        // 当满足一个时，退出循环
                        result = ruleValue.getEstimateLevel();
                        return result;
                    }
                    result = "所有公式均不符合";
                }
            }
        } catch (ScriptException e) {
            e.printStackTrace();
            result = "规则配置中服务异常，请检查";
            return result;
        }
        return result;
    }

    @Override
    public void updateDataByFillTask(String divisionCode, String year, List<IdtFillValue> values) {

        LambdaQueryWrapper<IdtMonitorValue> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(IdtMonitorValue::getDivisionCode,divisionCode);
        wrapper.eq(IdtMonitorValue::getYear,Integer.valueOf(year));
        wrapper.orderByDesc(IdtMonitorValue::getCreateTime);
        List<IdtMonitorValue> monitorValueList = this.list(wrapper);
        Map<String,List<IdtMonitorValue>> monitorValueMap = monitorValueList.stream().collect(Collectors.groupingBy(IdtMonitorValue::getIndicatorsId));

        List<IdtMonitorValue> saveList = new ArrayList<>();
        List<IdtMonitorValue> updateList = new ArrayList<>();

        for(IdtFillValue fillValue : values){
            IdtMonitorValue monitorValue;

            List<IdtMonitorValue> monitorValues = monitorValueMap.get(fillValue.getIndicatorsId());
            if(!CollectionUtils.isEmpty(monitorValues)){
                monitorValue = monitorValues.get(0);
                monitorValue.setMonitorValue(fillValue.getValue());
                monitorValue.setModifier(AuthUtil.getUserId().toString());
                monitorValue.setModifyTime(new Date());
                updateList.add(monitorValue);
            }else {
                monitorValue = new IdtMonitorValue();
                monitorValue.setId(UuidUtil.get32UUID());
                monitorValue.setCreateTime(new Date());
                monitorValue.setCreator(AuthUtil.getUserId().toString());
                monitorValue.setIndicatorsId(fillValue.getIndicatorsId());
                monitorValue.setYear(Integer.parseInt(year));
                monitorValue.setDivisionCode(divisionCode);
                monitorValue.setOrgId(AuthUtil.getDeptId());
                monitorValue.setMonitorValue(fillValue.getValue());
                monitorValue.setMonitorTime(year);
                saveList.add(monitorValue);
            }
        }
        if(!CollectionUtils.isEmpty(saveList)){
            this.saveBatch(saveList);
        }
        if(!CollectionUtils.isEmpty(updateList)){
            this.updateBatchById(updateList);
        }
    }
}
